
package org.dao.entitys;

// *************************************************************************/
// Area de Desarrollo de Sistemas de Información
// *************************************************************************/
// Proyecto : java dao controller
// Archivo : DataAccessObject.java
// Descripcion : Clase DataAccessObject
// *************************************************************************/
// Version : 2.10.4
// Fecha de Creación: 13 de Agosto de 2014
// Author : Daniel Andres Castillo Pedroza
// *************************************************************************/

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import org.sql.commands.exception.DMLException;
import org.sql.commands.mysql.clause.Where;
import org.sql.commands.mysql.command.Delete;
import org.sql.commands.mysql.command.ExecuteCommand;
import org.sql.commands.mysql.command.Insert;
import org.sql.commands.mysql.command.Select;
import org.sql.commands.mysql.command.Update;

public abstract class DataAccessObject <O> {
    
    // Atributos estáticos de la clase DataAccessObject
    
    protected static Connection CONNECTION;
    protected static String TIPO_COMANDO;
    
    // Atributos de la clase DataAccessObject
    
    protected Where WHERE;
    
    // Metodos de la clase DataAccessObject
    
    /**
      * 
      * @param object
      * @return
      * @throws SQLException
      * @throws DMLException 
    */
    
    protected boolean insert(O object) throws SQLException, DMLException {
      // Declarando y configurando objetos para el Proceso
      Insert insert = generateInsert();
      ArrayList datasInsert = generateDataInsert(object);
      
      // Ejecutando comando para Insertar Datos
      return ExecuteCommand.executeInsert(insert,datasInsert,CONNECTION);
    }
    
    /**
      * 
      * @return
      * @throws SQLException
      * @throws DMLException 
    */
    
    protected O selectUnique() throws SQLException, DMLException {
      // Declarando y configurando objetos para el Proceso
      Select select = generateSelect();
      
      // Ejecutando comando para Seleccionar Datos
      ResultSet resultSet = ExecuteCommand.executeSelect(select,CONNECTION);
      
      O object = null; // Dato a retornar en el Método
      
      if (resultSet.next()) {
        object = generateObject(resultSet);
      } // Recreando objetos Seleccionado en el Sistema
      
      // Cerrando conexiones con el Servidor
      resultSet.close(); ExecuteCommand.closedPrepared();
      
      return object; // Retornando Objeto cargado
    }
    
    /**
      * 
      * @param dato
      * @return
      * @throws SQLException
      * @throws DMLException 
    */
    
    protected O selectUnique(String dato) throws SQLException, DMLException {
      // Declarando y configurando objetos para el Proceso
      Select select = generateSelect();
      
      // Ejecutando comando para Seleccionar Datos
      ResultSet resultSet = ExecuteCommand.executeSelect(select,dato,CONNECTION);
      
      O object = null; // Dato a retornar en el Método
      
      if (resultSet.next()) {
        object = generateObject(resultSet);
      } // Recreando objetos Seleccionado en el Sistema
      
      // Cerrando conexiones con el Servidor
      resultSet.close(); ExecuteCommand.closedPrepared();
      
      return object; // Retornando Objeto cargado
    }
    
    /**
      * 
      * @param datos
      * @return
      * @throws SQLException
      * @throws DMLException 
    */
    
    protected O selectUnique(ArrayList datos) throws SQLException, DMLException {
      // Declarando y configurando objetos para el Proceso
      Select select = generateSelect();
      
      // Ejecutando comando para Seleccionar Datos
      ResultSet resultSet = ExecuteCommand.executeSelect(select,datos,CONNECTION);
      
      O object = null; // Dato a retornar en el Método
      
      if (resultSet.next()) {
        object = generateObject(resultSet);
      } // Recreando objetos Seleccionado en el Sistema
      
      // Cerrando conexiones con el Servidor
      resultSet.close(); ExecuteCommand.closedPrepared();
      
      return object; // Retornando Objeto cargado
    }
    
    /**
      * 
      * @return
      * @throws SQLException
      * @throws DMLException 
    */
    
    protected ArrayList <O> selectAll() throws SQLException, DMLException {
      // Instanciando, declarando y configurando objetos para el Proceso
      ArrayList <O> objects = new ArrayList <> ();
      Select select = generateSelect();
      
      // Ejecutando comando para Seleccionar Datos
      ResultSet resultSet = ExecuteCommand.executeSelect(select,CONNECTION);
      
      while (resultSet.next()) {
        objects.add(generateObject(resultSet));
      } // Recreando objetos Seleccionado en el Sistema
      
      // Cerrando conexiones con el Servidor
      resultSet.close(); ExecuteCommand.closedPrepared();
      
      return objects; // Retornando Objetos cargados
    }
    
    /**
      * 
      * @param dato
      * @return
      * @throws SQLException
      * @throws DMLException 
    */
    
    protected ArrayList <O> select(Object dato) throws SQLException, DMLException {
      // Declarando y configurando objetos para el Proceso
      ArrayList datos = new ArrayList(); datos.add(dato);
      
      return select(datos); // Retornando Objetos cargados
    }
    
    /**
     * 
     * @param datos
     * @return
     * @throws SQLException
     * @throws DMLException 
     */
    protected ArrayList <O> select(String ... datos) throws SQLException, DMLException {
        ArrayList datosTemp = new ArrayList(); // ArrayList para cargar los Datos
        
        for (String dato : datos) {
            datosTemp.add(dato);
        } // Cargando los datos del Vector en el Array
        
        return select(datosTemp); // Retornando el resultando de la Consulta
    }
    
    /**
      * 
      * @param datos
      * @return
      * @throws SQLException
      * @throws DMLException 
    */
    
    protected ArrayList <O> select(ArrayList datos) throws SQLException, DMLException {
      // Instanciando, declarando y configurando objetos para el Proceso
      ArrayList <O> objects = new ArrayList <> ();
      Select select = generateSelect();
      
      // Ejecutando comando para Seleccionar Datos
      ResultSet resultSet = ExecuteCommand.executeSelect(select,datos,CONNECTION);
      
      while (resultSet.next()) {
        objects.add(generateObject(resultSet));
      } // Recreando objetos Seleccionado en el Sistema
      
      // Cerrando conexiones con el Servidor
      resultSet.close(); ExecuteCommand.closedPrepared();
      
      return objects; // Retornando Objetos cargados
    }
    
    /**
      * 
      * @param object
      * @return
      * @throws SQLException
      * @throws DMLException 
    */
    
    protected int update(O object) throws SQLException, DMLException {
      // Declarando y configurando objetos para el Proceso
      Update update = generateUpdate();
      ArrayList updateDatas = generateDataUpdate(object);
      
      // Ejecutando comando para Actualizar Datos
      return ExecuteCommand.executeUpdate(update,updateDatas,CONNECTION);
    }
    
    /**
      * 
      * @return
      * @throws SQLException
      * @throws DMLException 
    */
    
    protected int deleteAll() throws SQLException, DMLException {
      // Declarando y configurando objetos para el Proceso
      Delete delete = generateDelete();
      
      // Ejecutando comando para Eliminar Datos
      return ExecuteCommand.executeDelete(delete,CONNECTION);
    }
    
    /**
      * 
      * @param dato
      * @return
      * @throws SQLException
      * @throws DMLException 
    */
    
    protected int delete(String dato) throws SQLException, DMLException {
      // Declarando y configurando objetos para el Proceso
      Delete delete = generateDelete();
      
      // Ejecutando comando para Eliminar Datos
      return ExecuteCommand.executeDelete(delete,dato,CONNECTION);
    }
    
    /**
      * 
      * @param datos
      * @return
      * @throws SQLException
      * @throws DMLException 
    */
    
    protected int delete(ArrayList datos) throws SQLException, DMLException {
      // Declarando y configurando objetos para el Proceso
      Delete delete = generateDelete();
      
      // Ejecutando comando para Eliminar Datos
      return ExecuteCommand.executeDelete(delete,datos,CONNECTION);
    }
    
    //<editor-fold defaultstate="collapsed" desc="'Metodos para configurar Sentencia Insert'">
    
    /**
      * 
      * @return 
    */
    
    protected abstract Insert generateInsert();
    
    /**
      * 
      * @param object
      * @return 
    */
    
    protected abstract ArrayList generateDataInsert(O object);
    
    //</editor-fold>
    
    //<editor-fold defaultstate="collapsed" desc="'Metodos para configurar Sentencia Select'">
    
    /**
      * 
      * @return 
    */
    
    protected abstract Select generateSelect();
    
    /**
      * 
      * @param result
      * @return 
      * @throws SQLException 
    */
    
    protected abstract O generateObject(ResultSet result) throws SQLException;
    
    //</editor-fold>
    
    //<editor-fold defaultstate="collapsed" desc="'Metodos para configurar Sentencia Update'">
    
    /**
      * 
      * @return 
    */
    
    protected abstract Update generateUpdate();
    
    /**
      * 
      * @param object
      * @return 
    */
    
    protected abstract ArrayList generateDataUpdate(O object);
    
    //</editor-fold>
    
    //<editor-fold defaultstate="collapsed" desc="'Metodos para configurar Sentencia Delete'">
    
    /**
      * 
      * @return 
    */
    
    protected abstract Delete generateDelete();
    
    //</editor-fold>
}